﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NextInventory.Model.Party;
using NextInventory.Data;

namespace NextInventory.Business.EntityRepositories
{
    public interface IPartyRepository : IBaseRepository
    {

        #region Party

        PartyModel GetPartyByID(int Id);
        List<PartyViewModel> GetAllParties(PartyViewModel filter, string sortColumn, string sortOrder, int pageSize, int pageIndex, out int totalRecords);
        List<PartyModel> GetPartyByModelID(int Id);
        List<ModeOfPayment> GetModeOfPaymentList();
        bool AddParty(PartyModel model, out string message);
        bool UpdateParty(PartyModel model, out string message, int partyId);
        bool DeleteParty(int Id);

        #endregion Party

    }

    public class PartyRepository : BaseRepository, IPartyRepository
    {

        #region Party

        public PartyModel GetPartyByID(int Id)
        {
            throw new NotImplementedException();
        }

        public List<PartyViewModel> GetAllParties(PartyViewModel filter, string sortColumn, string sortOrder, int pageSize, int pageIndex, out int totalRecords)
        {
            var party = (from p in _Contaxt.Parties.Include("ModeOfPayment")
                         //join ps in _Contaxt.PartyStatus
                         //on p.PartyStatusId equals ps.PartyStatusId
                         //join m in _Contaxt.ModeOfPayments
                         //on p.ModeOfPaymentId equals m.ModeOfPaymentId
                         orderby p.FirstName
                         select new PartyViewModel
                         {
                             ID = p.PartyId,
                             Name = p.FirstName + " " + p.LastName,
                             Phone = p.Phone,
                             Email = p.Email,
                             CreditLimit = p.CreditLimit,
                             Balance = p.Balance,
                             Address = p.Address,
                             ModeOfPayment = p.ModeOfPayment.Name,
                             //PartyStatus = ps.Name
                         });
            //if (!string.IsNullOrEmpty(filter.Name))
            //{
            //    party = party.Where(p => p.Name.ToLower().Contains(filter.Name.ToLower()));
            //}
            //if (!string.IsNullOrEmpty(filter.Phone))
            //{
            //    party = party.Where(p => p.Phone.Contains(filter.Phone));
            //}
            //if (!string.IsNullOrEmpty(filter.Email))
            //{
            //    party = party.Where(p => p.Email.ToLower().Contains(filter.Email.ToLower()));
            //}
            //if (filter.CreditLimit != 0)
            //{
            //    party = party.Where(p => p.CreditLimit.ToString().Contains(filter.CreditLimit.ToString()));
            //}
            //if (filter.Balance != 0)
            //{
            //    party = party.Where(p => p.Balance.ToString().Contains(filter.Balance.ToString()));
            //}
            //if (!string.IsNullOrEmpty(filter.Address))
            //{
            //    party = party.Where(p => p.Address.Contains(filter.Address));
            //}
            //if (!string.IsNullOrEmpty(Convert.ToString(filter.ModeOfPayment)))
            //{
            //    party = party.Where(p => p.ModeOfPayment.ToString().Contains(filter.ModeOfPayment.ToString()));
            //}
            //if (!string.IsNullOrEmpty(Convert.ToString(filter.PartyStatus)))
            //{
            //    party = party.Where(p => p.PartyStatus.ToString().Contains(filter.PartyStatus.ToString()));
            //}
            switch (sortColumn)
            {
                case "Name":
                    party = (sortOrder == "desc") ? party.OrderByDescending(p => p.Name) : party.OrderBy(p => p.Name);
                    break;
                case "Phone":
                    party = (sortOrder == "desc") ? party.OrderByDescending(p => p.Phone) : party.OrderBy(p => p.Phone);
                    break;
                case "Email":
                    party = (sortOrder == "desc") ? party.OrderByDescending(p => p.Email) : party.OrderBy(p => p.Email);
                    break;
                case "CreditLimit":
                    party = (sortOrder == "desc") ? party.OrderByDescending(p => p.CreditLimit) : party.OrderBy(p => p.CreditLimit);
                    break;
                case "Balance":
                    party = (sortOrder == "desc") ? party.OrderByDescending(p => p.Balance) : party.OrderBy(p => p.Balance);
                    break;
                case "Address":
                    party = (sortOrder == "desc") ? party.OrderByDescending(p => p.Address) : party.OrderBy(p => p.Address);
                    break;
                case "ModeOfPayment":
                    party = (sortOrder == "desc") ? party.OrderByDescending(p => p.ModeOfPayment) : party.OrderBy(p => p.ModeOfPayment);
                    break;
                //case "PartyStatus":
                //    party = (sortOrder == "desc") ? party.OrderByDescending(p => p.PartyStatus) : party.OrderBy(p => p.PartyStatus);
                //    break;
                default:
                    break;
            }
            totalRecords = party.Count();
            return party.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();

        }
        public List<PartyModel> GetPartyByModelID(int Id)
        {
            throw new NotImplementedException();
        }

        public bool AddParty(PartyModel model, out string message)
        {
            NextInventoryContext context = new NextInventoryContext();
            if (string.IsNullOrEmpty(model.FirstName))
            {
                message = "First name is required.";
                return false;
            }
            if (string.IsNullOrEmpty(model.LastName))
            {
                message = "Last name is required.";
                return false;
            }
            if (string.IsNullOrEmpty(model.Phone))
            {
                message = "Phone number is required.";
                return false;
            }
            if (string.IsNullOrEmpty(model.Email))
            {
                message = "Email is required.";
                return false;
            }
            if (string.IsNullOrEmpty(model.Address))
            {
                message = "Address is required.";
                return false;
            }
            if (string.IsNullOrEmpty(model.City))
            {
                message = "City name is required.";
                return false;
            }
            if (string.IsNullOrEmpty(model.Country))
            {
                message = "Country name is required.";
                return false;
            }
            if (string.IsNullOrEmpty(model.CreditLimit.ToString()))
            {
                message = "Credit limit is required.";
                return false;
            }

            Party party = new Party()
            {
                FirstName = model.FirstName,
                LastName = model.LastName,
                Phone = model.Phone,
                Email = model.Email,
                Address = model.Address,
                City = model.City,
                Country = model.Country,
                CreditLimit = model.CreditLimit,
                ModeOfPaymentId = model.ModeOfPaymentId,
                PartyStatusId = model.PartyStatusId
            };

            context.Parties.Add(party);
            context.SaveChanges();
            if (party.PartyId > 0)
            {
                message = "Party successfully saved.";
                return true;
            }
            else
            {
                message = "Error accured saving party";
                return false;
            }
        }

        public bool UpdateParty(PartyModel model, out string message, int partyId)
        {
            NextInventoryContext context = new NextInventoryContext();
            if (string.IsNullOrEmpty(model.FirstName))
            {
                message = "First name is required.";
                return false;
            }
            if (string.IsNullOrEmpty(model.LastName))
            {
                message = "Last name is required.";
                return false;
            }
            if (string.IsNullOrEmpty(model.Phone))
            {
                message = "Phone number is required.";
                return false;
            }
            if (string.IsNullOrEmpty(model.Email))
            {
                message = "Email is required.";
                return false;
            }
            if (string.IsNullOrEmpty(model.Address))
            {
                message = "Address is required.";
                return false;
            }
            if (string.IsNullOrEmpty(model.City))
            {
                message = "City name is required.";
                return false;
            }
            if (string.IsNullOrEmpty(model.Country))
            {
                message = "Country name is required.";
                return false;
            }
            if (string.IsNullOrEmpty(model.CreditLimit.ToString()))
            {
                message = "Credit limit is required.";
                return false;
            }
            Party party = context.Parties.FirstOrDefault(o => o.PartyId == model.PartyId);

            if (party == null)
            {
                message = "Party not exist";
                return false;
            }
            //party.FirstName = model.FirstName,
            //party.LastName = model.LastName,
            //party.Phone = model.Phone,
            //party.
            throw new NotImplementedException();
        }

        public bool DeleteParty(int Id)
        {
            NextInventoryContext context = new NextInventoryContext();
            Party party = context.Parties.FirstOrDefault(o => o.PartyId == Id);
            context.Parties.Remove(party);
            context.SaveChanges();
            return true;
        }
        public List<ModeOfPayment> GetModeOfPaymentList()
        {
            NextInventoryContext context = new NextInventoryContext();
            return (from modeOfPayment in context.ModeOfPayments select modeOfPayment).ToList();
            throw new NotImplementedException();
        }
        #endregion Party
    }
}
